package com.smartmail.receiving;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import android.os.Environment;
import android.util.Log;

import com.smartmail.mailing.MailMessage;
import com.smartmail.mime.MimeParser;
import com.smartmail.utility.MessageUtility;

/**
 * Class responsible for writing and reading messages from the phone's internal memory - SD card.
 * This class contains two subclasses - IMAP and POP3 - which contain methods specific to the protocol.
 * @author Tomek
 *
 */
public class InternalStorageUtility {
	
	
	/**
	 * The method removes the message from the phone's internal memory.
	 * 
	 * @param mailMessage - MailMessage object which identify message to be deleted from SD card
	 * @return - true when deleting succeed, otherwise false
	 */
	public static boolean deleteMessageFromSDCard(MailMessage mailMessage) {

		String filePath = Environment.getExternalStorageDirectory()
				.getAbsolutePath()
				+ "/"
				+ storeDir
				+ "/"
				+ mailMessage.getMessageHash() + ".dat";
		File fileToDelete = new File(filePath);
		boolean deleted = fileToDelete.delete();

		return deleted;
	}


	/**
	 * Class containing specific to POP3 protocol methods used with saving/retrieving 
	 * messages to/from internal memory (SD card).
	 * 
	 * @author Tomek
	 *
	 */
	public static class POP3{
		
		
		/**
		 * Method which retrieved full MimeMessage object from internal memory.
		 * 
		 * @param mailMessage - MailMessage object which identifies message
		 *  to be retrieved from internal memory.
		 *  
		 * @return - MimeMessage object, retrieved from internal memory, 
		 * or null if retrieving end with failure.
		 */
		public static MimeMessage retrieveFromMemory(MailMessage mailMessage) {

			MimeMessage message = null;
			FileInputStream f = null;

			try {
				String msgPath = mailMessage.getMsgPath();
				File sdCard = Environment.getExternalStorageDirectory();
				
				File dir = new File(
						sdCard.getAbsolutePath() 
						+ "/" + storeDir + "/"
						+ msgPath);
				
				f = new FileInputStream(dir);
				message = new MimeMessage(null, f);
				f.close();
				
			} catch (Exception e) {

				Log.d(_logTag,
						"InternalStorageUtil : error while retrieving message from device");
				return null;
			}

			return message;

		}
		
		/**
		 * The method which saves the entire contents of the messages in the phone's internal memory.
		 * 
		 * @param mimeMessage - MimeMessage object which will be stored in internal memory.
		 * @return - path to the file that contains the entire message.
		 */
		public static String writeWholeMessageOnSDCard(MimeMessage mimeMessage) {

			String fileName = null;
			try {
				/**
				 * save message to sd card
				 */
				File dir = new File(Environment.getExternalStorageDirectory(),
						storeDir);
				if (!dir.exists()) {
					if (!dir.mkdirs()) {
						Log.e(_logTag, "InternalStorageUtil : Problem creating Image folder");

					}
				}

				String messageHash = MessageUtility.getHash(mimeMessage);

				fileName = messageHash + ".dat";
				File file = new File(dir, fileName);
				FileOutputStream f = new FileOutputStream(file);

				mimeMessage.writeTo(f);
				f.close();
			} catch (MessagingException e) {

				Log.d(_logTag,
						"InternalStorageUtil : messaging exception while writing on sd card");
				return null;
			} catch (FileNotFoundException e) {

				Log.d(_logTag,
						"InternalStorageUtil : file not found exception while writing on sd card");
				return null;
			} catch (IOException e) {

				Log.d(_logTag, "InternalStorageUtil : IO exception while writing on sd card");
				return null;
			}
			return fileName;
		}
		
		
	}

	/**
	 * 
	 * Class containing specific to IMAP protocol methods used with saving/retrieving 
	 * messages to/from internal memory (SD card).
	 * @author Tomek
	 *
	 */
	public static class IMAP{
		
		/**
		 * The method returns the text of the message, taken from a cache stored in internal memory.
		 * 
		 * @param mailMessage - MailMessage object which identifies message.
		 * @return - Content of message, as message's text.
		 */
		public static String retrieveContentFromCache(MailMessage mailMessage) {
			
			FileInputStream f = null;
			String content = null;

			try {
				String msgPath = mailMessage.getMsgPath();
				File sdCard = Environment.getExternalStorageDirectory();
				
				File dir = new File(
						sdCard.getAbsolutePath() + 
						"/" + storeDir + "/"
						+ msgPath);
				
				f = new FileInputStream(dir);
				content = new Scanner(f).useDelimiter("\\A").next();

				
				f.close();
			} catch (Exception e) {

				Log.d(_logTag,
						"MimeParser : error while retrieving message from device");
				return null;
			}

			return content;
		}
		
		/**
		 * The method which saves text part of message in internal phone memory.
		 * 
		 * @param mimeMessage - MailMessage object which identifies message.
		 * @return -  - path to the file which contains text part of message.
		 */
		public static String writeCacheOnSDCard(MimeMessage mimeMessage) {

			String fileName = null;
			try {
				/**
				 * save message to sd card
				 */
				File dir = new File(Environment.getExternalStorageDirectory(),
						storeDir);
				if (!dir.exists()) {
					if (!dir.mkdirs()) {
						Log.e(_logTag, "Problem creating Image folder");

					}
				}

				String messageHash = MessageUtility.getHash(mimeMessage);

				fileName = messageHash + ".dat";
				File file = new File(dir, fileName);
				FileOutputStream f = new FileOutputStream(file);
				PrintWriter pw = new PrintWriter(f);
				
				String content = MimeParser.getText(mimeMessage);
				pw.write(content);
				pw.close();
				f.close();
				
			} catch (MessagingException e) {

				Log.d(_logTag,
						"MimeParser : messaging exception while writing on sd card");
				return fileName;
			} catch (FileNotFoundException e) {

				Log.d(_logTag,
						"MimeParser : file not found exception while writing on sd card");
				return fileName;
			} catch (IOException e) {

				Log.d(_logTag, "MimeParser : IO exception while writing on sd card");
				Log.d(_logTag, e.getMessage() + " " + e.toString());
				for(StackTraceElement elem : e.getStackTrace())
					Log.d(_logTag, elem.toString());
				return fileName;
			} 
			return fileName;
			
		}
		
		
	}
	
	/**
	 * log tag for logging purposes
	 */
	private static String _logTag = "com.smartmail.receiving";
	
	/**
	 * Folder on the SD card, when all received messages are stored.
	 */
	private static String storeDir = "smartMail";


}
